/*
 *  This file is part of BBBFlashCard.
 *
 *  BBBFlashCard is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  BBBFlashCard is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with BBBFlashCard.  If not, see <http://www.gnu.org/licenses/>.
 */
package hu.bbb.flashcard.model;


import java.io.UnsupportedEncodingException;

/**
 *
 * @author bsudy
 */
public class FlashCard {

    private final String sideA;
    private final String sideB;

    private int deck = 0;
    private int lastSuccess = 0;

    private int reverseDeck = 0;
    private int lastReverseSuccess = 0;

    public FlashCard(final String sideA, final String sideB) {
        this.sideA = sideA;
        this.sideB = sideB;
    }

    public FlashCard(final String sideA, final String sideB, final int deck, final int lastSuccess, final int reverseDeck, final int lastReverseSuccess) {
        this.sideA = sideA;
        this.sideB = sideB;
        this.deck = deck;
        this.lastSuccess = lastSuccess;
        this.reverseDeck = reverseDeck;
        this.lastReverseSuccess = lastReverseSuccess;
    }



    public int getDeck(final boolean reverse) {
        if (reverse) {
            return this.reverseDeck;
        }
        return this.deck;
    }

    public int getLastSuccess(final boolean reverse) {
        if (reverse) {
            return this.lastReverseSuccess;
        }
            return this.lastSuccess;
    }

    public String getSideA() {
        return this.sideA;
    }

    public String getSideB() {
        return this.sideB;
    }

    public void success(final int sessionNumber, final boolean reverse) {
        System.out.println("Success:" + this.sideA + " " + sessionNumber);
        if (reverse) {
            this.reverseDeck ++;
            this.lastReverseSuccess = sessionNumber;
        } else {
            this.deck ++;
            this.lastSuccess = sessionNumber;
        }
    }

    public void failure(final boolean reverse) {
        System.out.println("failure:" + this.sideA);
        if (reverse) {
            this.reverseDeck = 0;
        } else {
            this.deck = 0;
        }

    }

    public String getRecordStoreName() {
        return "flashcard";
    }


    public byte[] getBytes() throws UnsupportedEncodingException {

        final byte[] sideABytes = this.sideA.getBytes("UTF-8");
        final byte[] sideASizeBytes = intToByte(sideABytes.length);
        final byte[] sideBBytes = this.sideB.getBytes("UTF-8");
        final byte[] sideBSizeBytes = intToByte(sideBBytes.length);

        final byte[] deckBytes = intToByte(this.deck);
        final byte[] lastSuccessBytes = intToByte(this.lastSuccess);
        final byte[] reverseDeckBytes = intToByte(this.reverseDeck);
        final byte[] reverseLastSuccessBytes = intToByte(this.lastReverseSuccess);


        final int length = sideASizeBytes.length +
                sideABytes.length +
                sideBSizeBytes.length +
                sideBBytes.length +
                deckBytes.length +
                lastSuccessBytes.length +
                reverseDeckBytes.length +
                reverseLastSuccessBytes.length;

        final byte[] ret = new byte[length];
        int pos = 0;
        System.arraycopy(sideASizeBytes, 0, ret, pos, sideASizeBytes.length);
        pos += sideASizeBytes.length;

        System.arraycopy(sideABytes, 0, ret, pos, sideABytes.length);
        pos += sideABytes.length;

        System.arraycopy(sideBSizeBytes, 0, ret, pos, sideBSizeBytes.length);
        pos += sideBSizeBytes.length;

        System.arraycopy(sideBBytes, 0, ret, pos, sideBBytes.length);
        pos += sideBBytes.length;

        System.arraycopy(deckBytes, 0, ret, pos, deckBytes.length);
        pos += deckBytes.length;

        System.arraycopy(lastSuccessBytes, 0, ret, pos, lastSuccessBytes.length);
        pos += lastSuccessBytes.length;

        System.arraycopy(reverseDeckBytes, 0, ret, pos, reverseDeckBytes.length);
        pos += reverseDeckBytes.length;

        System.arraycopy(reverseLastSuccessBytes, 0, ret, pos, reverseLastSuccessBytes.length);
        pos += reverseLastSuccessBytes.length;

        return ret;
    }



    public static byte[] intToByte(final int i) {
        final byte[] bytes = new byte[4];
        bytes[0] =(byte)( i >> 24 );
        bytes[1] =(byte)( i << 8 >> 24 );
        bytes[2] =(byte)( i << 16 >> 24 );
        bytes[3] =(byte)( i << 24 >> 24 );
        return bytes;
    }

    public static int byteToInt(final byte[] b) {
        int i = 0;
        i |= b[0] & 0xFF;
        i <<= 8;
        i |= b[1] & 0xFF;
        i <<= 8;
        i |= b[2] & 0xFF;
        i <<= 8;
        i |= b[3] & 0xFF;
        return i;
    }

    public static FlashCard parseBytes(final byte[] bytes) throws UnsupportedEncodingException {




        final byte[] sideASizeBytes = new byte[4];

        final byte[] sideBSizeBytes = new byte[4];

        final byte[] deckBytes = new byte[4];
        final byte[] lastSuccessBytes = new byte[4];
        final byte[] reverseDeckBytes = new byte[4];
        final byte[] reverseLastSuccessBytes = new byte[4];


        int pos = 0;
        System.arraycopy(bytes, pos, sideASizeBytes, 0, 4);
        pos += 4;
        final int sideASize = byteToInt(sideASizeBytes);

        final byte[] sideABytes = new byte[sideASize];
        System.arraycopy(bytes, pos, sideABytes, 0, sideASize);
        pos += sideASize;

        System.arraycopy(bytes, pos, sideBSizeBytes, 0, 4);
        pos += 4;
        final int sideBSize = byteToInt(sideBSizeBytes);

        final byte[] sideBBytes = new byte[sideBSize];
        System.arraycopy(bytes, pos, sideBBytes, 0, sideBSize);
        pos += sideBSize;

        System.arraycopy(bytes, pos, deckBytes, 0, 4);
        pos += 4;

        System.arraycopy(bytes, pos, lastSuccessBytes, 0, 4);
        pos += 4;

        System.arraycopy(bytes, pos, reverseDeckBytes, 0, 4);
        pos += 4;

        System.arraycopy(bytes, pos, reverseLastSuccessBytes, 0, 4);
        pos += 4;

        final String sideA = new String(sideABytes, "UTF-8");
        final String sideB = new String(sideBBytes, "UTF-8");

        final int deck = byteToInt(deckBytes);
        final int lastSuccess = byteToInt(lastSuccessBytes);

        final int reverseDeck = byteToInt(reverseDeckBytes);
        final int lastReverseSuccess = byteToInt(reverseLastSuccessBytes);

        return new FlashCard(sideA, sideB, deck, lastSuccess, reverseDeck, lastReverseSuccess);
    }

}
